#include "Common.h"

#include "Crc/App_Crc.h"

/***********************************************************
 * Function Name:       AppCrc8_PositiveCalVerify
 * Description:         CRC8计算法（多项式0x31 正序）
 * Parameters[in]:      IN UCHAR *ptr
                        IN UINT16 usLength
 * Parameters[ou]: 
 * ReturnValue:         校验值
 * Author:              liuke
 * Date:                2019.1.4
***********************************************************/
UCHAR AppCrc8_PositiveCalVerify(IN UCHAR *ptr, IN USHORT usLength)
{
    UCHAR i = 0; 
    UCHAR ucCrc = 0x00; /* 计算的初始crc值 */ 
 
    while (usLength--)
    {
        ucCrc ^= *ptr++;  /* 每次先与需要计算的数据异或,计算完指向下一数据 */  
        for (i = 8; i > 0; --i)   /* 下面这段计算过程与计算一个字节crc一样 */  
        { 
            if (ucCrc & 0x80)
                ucCrc = (ucCrc << 1) ^ 0x31;
            else
                ucCrc = (ucCrc << 1);
        }
    }
 
    return ucCrc; 
}

/**********************************************************
 * Function Name:       AppCrc8_ReverseCalVerify
 * Description:         CRC8逆序（多项式0x31）：计算法校验
 * Parameters[in]:      IN UCHAR *ptr
                        IN USHORT usLength
 * Parameters[ou]: 
 * ReturnValue:         校验值
 * Author:              liuke
 * Date:                2019.1.4
**********************************************************/
UCHAR AppCrc8_ReverseCalVerify(IN UCHAR *ptr, IN USHORT usLength)
{
    UCHAR i = 0;
    UCHAR ucCrc = 0xFF; /* 计算的初始crc值 */

    while (usLength--)
    {
        ucCrc ^= *ptr++;  /* 每次先与需要计算的数据异或,计算完指向下一数据 */
        for (i = 8; i > 0; --i)   /* 下面这段计算过程与计算一个字节crc一样 */
        {
            if (ucCrc & 0x01)
                ucCrc = (ucCrc >> 1) ^ 0x8C;
            else
                ucCrc = (ucCrc >> 1);
        }
    }

    return ucCrc ^ 0xFF;
}

/**********************************************************
 * Function Name:       AppCrc16_PositiveCalVerify
 * Description:         CRC16正序（多项式0x1021）
                        计算法校验
 * Parameters[in]:      IN UCHAR *pcBuf
                        IN UINT16 usLength
 * Parameters[ou]:      无
 * ReturnValue:         校验值
 * Author:              liuke
 * Date:                2019.1.4
**********************************************************/
UINT16 AppCrc16_PositiveCalVerify(IN UCHAR *pcBuf, IN USHORT usLength)
{
    UINT16 i = 0;
    UINT16 usCRC = 0x0000;

    while ( usLength-- ) 
    {
        usCRC ^= ((*pcBuf) << 8);
        
        for(i = 0x80; i != 0; i >>= 1) 
        {
            if((usCRC & 0x8000) != 0) 
            {
                usCRC = usCRC << 1;
                usCRC = usCRC ^ 0x1021;
            }
            else
            {
                usCRC = usCRC << 1;
            }
        }
        
        pcBuf++;
    }

    return usCRC;
} 

/* CCITT  0x8408 逆序 */
/**********************************************************
 * Function Name:       AppCrc16_ReverseCalVerify
 * Description:         CRC16逆序序（多项式0x1021）
                        计算法校验
 * Parameters[in]:      IN UCHAR *pcBuf
                        IN UINT16 usLength
 * Parameters[ou]:      无
 * ReturnValue:         校验值
 * Author:              liuke
 * Date:                2019.1.4
**********************************************************/
UINT16 AppCrc16_ReverseCalVerify(IN UCHAR *pcBuf, IN USHORT usLength)
{
    UINT16 i = 0;
    UINT16 usCRC = 0xFFFF;

    while( usLength-- ) 
    {
        usCRC ^= *pcBuf;
        
        for(i = 0x80; i != 0; i >>= 1) 
        {
            if((usCRC & 1) != 0) 
            {
                usCRC = usCRC >> 1;
                usCRC = usCRC ^ 0x8408;
            }
            else
            {
                usCRC = usCRC >> 1;
            }
        }
        
        pcBuf++;
    }

    return usCRC ^ 0xFFFF;
} 

/**********************************************************
 * Function Name:       AppCrc32_PositiveCalVerify
 * Description:         CRC32正序（多项式0x04c11db7L）
                        计算法校验
 * Parameters[in]:      IN UCHAR *pcBuf
                        IN USHORT usLength
 * Parameters[ou]:      无
 * ReturnValue:         校验值
 * Author:              liuke
 * Date:                2019.1.4
**********************************************************/
UINT32 AppCrc32_PositiveCalVerify(IN UCHAR *pcBuf, IN USHORT usLength)
{
    UINT32 i = 0;
    UINT32 uiCrc = 0;

    while( usLength-- ) 
    {
        uiCrc ^= ((*pcBuf) << 24);
        
        for(i = 0; i < 8; i++)
        {
            if((uiCrc & 0x80000000) != 0) 
            {
                uiCrc = uiCrc << 1;
                uiCrc = uiCrc ^ 0x04c11db7L;
            }
            else
            {
                uiCrc = uiCrc << 1;
            }
        }
        
        pcBuf++;
    }

    return uiCrc;
} 

/**********************************************************
 * Function Name:       AppCrc32_ReverseCalVerify
 * Description:         CRC32逆序（多项式0xEDB88320）
                        计算法校验
 * Parameters[in]:  I   N UCHAR *pcBuf
                        IN UINT16 usLength
 * Parameters[ou]:      无
 * ReturnValue:         校验值
 * Author:              liuke
 * Date:                2019.1.4
**********************************************************/
UINT32 AppCrc32_ReverseCalVerify(IN UCHAR *pcBuf, IN USHORT usLength)
{
    UINT32 i = 0;
    UINT32 uiCrc = 0xFFFFFFFF;

    while( usLength-- ) 
    {
        uiCrc ^= *pcBuf;
        
        for(i = 0x80; i != 0; i >>= 1) 
        {
            if((uiCrc & 1) != 0) 
            {
                uiCrc = uiCrc >> 1;
                uiCrc = uiCrc ^ 0xEDB88320;
            }
            else
            {
                uiCrc = uiCrc >> 1;
            }
        }
        
        pcBuf++;
    }

    return uiCrc ^ 0xFFFFFFFF;
} 


